/*
 * Copyright Iain Sproat, 2008
 * 
 *
 */

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

using NUnit.Framework;
using Rhino.Mocks;
using log4net;
using log4net.Config;

using FreeBase;
using FreeBase.Domain;
using FreeBase.Linq;
using FreeBase.Fluent;

using Newtonsoft.Json;

namespace FreeBase_Test.Linq
{
	[TestFixture]
	public class TestFreebaseExpressionVisitor
	{
		private readonly ILog logger = LogManager.GetLogger(typeof(TestFreebaseExpressionVisitor));
		
		MockRepository mocks = null;
		IFreebaseClient client = null;
		IQueryProvider prov = null;
		FreeBase.Fluent.MQLConverter.IMQLConverter conv = null;
		FreebaseExpressionVisitor SUT = null;
		
		[SetUp]
		public void SetUp()
		{
			//setup logging
			BasicConfigurator.Configure();
			
			//setup mocks
			mocks = new MockRepository();
			client = mocks.DynamicMock<IFreebaseClient>( );
			prov = new FreebaseQueryProvider( client );
			conv = new FreeBase.Fluent.MQLConverter.FluentMQLConverter();
			SUT = new FreebaseExpressionVisitor();
			
		}
		
		[Test]
		public void TestMethod()
		{
			Query<Artist> queryable = new Query<Artist>( prov );
			var q =
				from artist in queryable
				where
				artist.Name == "The Police" &&
				artist.Type == "/music/artist"
				select artist.Album;
			
			IQueryable query = q as IQueryable;
			Assert.IsNotNull( query );
			
			//logger.Debug( "expression is : " + query.Expression.ToString() );
			//FBQuery fluent = SUT.ProcessExpression( query.Expression );
			
			//string returned = conv.FluentToMQL( fluent );
			//logger.Debug( "returned MQL is : " + returned );
			
			string expected = "{\"query\":[{" +
				"\"album\":[]," +
				"\"name\":\"The Police\"," +
				"\"type\":\"/music/artist\"" +
				"}]}";
			Assert.IsTrue( ExpressionEqualsExpectedMQL( expected, query.Expression ) );
		}
		#region Helpers
		private bool ExpressionEqualsExpectedMQL( string expectedMQL, Expression e )
		{
			if( string.IsNullOrEmpty( expectedMQL ) )
				return false;
			if( e == null )
				return false;
			
			logger.Debug( "expression is " + e.ToString() );
			FBQuery fluent = SUT.ProcessExpression( e );
			
			string generatedMQL = conv.FluentToMQL( fluent );
			logger.Debug( "returned MQL is : " + generatedMQL );
			
			return expectedMQL.Equals( generatedMQL );
		}
		#endregion
		
	}
}
